#from __future__ import *

from visual import *
import time
import pickle
import commands
import os

from PythonCard import model, dialog

from teren import Teren
from robot import Robot
from history import HistoryVisualisation
from action_menu import ActionMenu, ExecutedItem
from Brain.plan import Plan
from Brain.vector import Vector
from Brain.planer.dialogs.CompoundCondition import execute_compoundcondition_dialog

VERSION = '0.9.1'

class TextOverlay:
	def __init__(self, dialog_parent):
		self._coordinate_label = label(xoffset=-30, yoffset=10, height=14, border=10, space=4 )
		self.menu = ActionMenu(dialog_parent)
		self._menu_shown = False 
	
	def on_mousemove(self, pointed):
		self._coordinate_label.pos = pointed
		self._coordinate_label.text = '(%.1f, %.1f)' % (pointed[0], pointed[1],)
		if self._menu_shown:
			self.menu.on_mousemove_event(pointed) 
	
	def on_keyinput(self, key, plan, history):
		#print 'aaaaaaa', key
		if self._menu_shown:
			if key == '\n':
				self._menu_shown = False
				self.menu.hide()
				return True 
			else:
				try:
					return self.menu.on_key_event(key, plan)
				except ExecutedItem, item:
					self._menu_shown = False 
					## update history:
					history.update(plan)
					return True 
#				except:
#					return False
		else:
			if key == '\n':
				self._menu_shown = True 
				self.menu.show()
				return True 
		return False

class Planer:
	
	REFRESH_INTERVAL = 1.0/30.0
	PAN_INCREMENT = 100.0
	OUTPUT_FILENAME = 'plan.pln'
	
	def __init__(self, plan_to_edit=None, dialog_parent=None):
		self._dialog_parent = dialog_parent
		if plan_to_edit == None:
			self._current_plan = Plan('Create Plans')
			self._editing_plan = False
		else:
			self._current_plan = plan_to_edit
			self._editing_plan = True
		self._last_ts = 0.0
		self._enabled = True
		self._pointed_position = (0.0, 0.0, 0.0)
		self._range = 1800.0
		self._history = None
		self._blinking = False
		
		self.mainwnd = display(title=str(self._current_plan._name), x=550, width=1024, height=768, center=(0,0,0), background=(0,0,0))
		self.mainwnd.select()
		self.teren = Teren()
		self.robot = Robot()
		self.mainwnd.visible = 1
		self.mainwnd.exit = 0
		self.mainwnd.autocenter = False
		self.mainwnd.uniform = 1
		self.mainwnd.autoscale = 0
		self.mainwnd.show_rendertime = True
		self._overlay = TextOverlay(self._dialog_parent)
		
		self._history = HistoryVisualisation()
		self._history.update(self._current_plan)	## update plan display
		
		print self.usage
	
	def run(self):		
		while self.mainwnd.visible:
			rate(60)
			
			if self._blinking: self.robot.blink()
			
			if self.mainwnd.mouse.events:
				state = self.mainwnd.mouse.getevent()
				if state.press == 'left':
					pointed = self.mainwnd.mouse.project( normal=(0,0,1), point=(0,0,0) )
					if pointed:
						self._click_event(pointed)
			elif self.mainwnd.kb.keys:
				data = self.mainwnd.kb.getkey()
				is_handled = 	self._overlay.on_keyinput(data, self._current_plan, self._history) or \
								self._key_event(data)
			else:
				self.heartbeat()
				time.sleep(0.0001)

	def heartbeat(self):
		""" does update of the scene, mousemove is not available
		"""
		diff = time.time() - self._last_ts
		if diff > self.REFRESH_INTERVAL:
			self._last_ts = time.time()
			if self._enabled:
				## mousemove:
				pointed = self.mainwnd.mouse.project( normal=(0,0,1), point=(0,0,0) )
				if pointed:
					if pointed != self._pointed_position:
						self._pointed_position = pointed
						#move robot model
						self.robot.move(pointed)
						self._history.update_pointer(Vector(pointed[0], pointed[1]))
						self.robot.rotate( self._history.get_current_direction() )
						# display labels
						self._overlay.on_mousemove(pointed)
	
	def _click_event(self, pointed):
		print pointed
		self._current_plan.add_movement_step(pointed[0], pointed[1])
		self._history.update(self._current_plan)
	
	def _key_event(self, data):
		if data == 'up': self.mainwnd.center.y += self.PAN_INCREMENT
		elif data == 'down': self.mainwnd.center.y -= self.PAN_INCREMENT
		elif data == 'left': self.mainwnd.center.x -= self.PAN_INCREMENT
		elif data == 'right': self.mainwnd.center.x += self.PAN_INCREMENT
		elif data == '-' :
			self._range *= 1.2
			self.mainwnd.range = self._range
		elif data == '+' :
			self._range *= 0.8
			self.mainwnd.range = self._range
		elif data == 'backspace':
			print ' - remove last step ..'
			self._current_plan.remove_last_step()
			self._history.update(self._current_plan)	## update plan display
		
		elif data == 'f1':
			if self._editing_plan:
				print 'loading not allowed during editing existing plan.'
			else:
				try:
					result = dialog.openFileDialog(wildcard='*.pln;*.plan')
					if result.accepted:
						filepath = result.paths[0]
						self._current_plan = pickle.load(open(filepath, 'rb'))
						self._history.update(self._current_plan)	## update plan display
				except:
					print ' ERROR loading failed !'
		elif data == 'f5':
			result = dialog.saveFileDialog(wildcard='*.pln;*.plan')
			if result.accepted:
				filepath = result.paths[0]
				pickle.dump(self._current_plan, open(filepath, 'wb'))
		
		elif data == 'f6':
			self._history.toggle_pointer()
		elif data == 'f7':
			self._history.toggle_trail()
		elif data == 'f2':
			self._blinking = not self._blinking
		
		elif data == 'f10':
			try:
				result = dialog.textEntryDialog(self._dialog_parent, 'min: ', 'edit minimal duration', str(self._current_plan.timelimit_bottom))
				if result.accepted:
					min_ = float(result.text)
					result = dialog.textEntryDialog(self._dialog_parent, 'max: ', 'edit maximal duration', str(self._current_plan.timelimit))
					if result.accepted:
						max_ = float(result.text)
						self._current_plan.timelimit_bottom, self._current_plan.timelimit, = min_, max_,
						print 'new time constraints %s - %s' % (min_, max_, )
			except:
				print 'time constraints not changed'
		
		elif data == 'f11':
			result = dialog.textEntryDialog(self._dialog_parent, 'name: ', 'edit name', self._current_plan._name)
			if result.accepted:
				self._current_plan._name = str(result.text)
				self.mainwnd.title = self._current_plan._name
		
		elif data == 'f12':
			ret = execute_compoundcondition_dialog(self._current_plan._start_condition)
			if ret.compound_condition:
				self._current_plan._start_condition = ret.compound_condition
				print 'start conditions changed :'
				print str(ret.compound_condition)
		else:
			print 'key: %s' % (repr(data), )
			return False
		return True

	usage = """
  left mouse click - create move step
  backspace - removes last step 

  - up - pan camera up  
  - down - pan camera down  
  - left - pan camera left  
  - right - pan camera right 
  - zoom out  
  + zoom in 
  
  F1 - LOAD 
  F5 - SAVE 
  
  F2 - toggle blink
  F6 - toggle pointer
  F7 - toggle trail
  
  F10 - edit time constraints 
  F11 - edit name
  F12 - edit start conditions 
  enter - insert Action
  
"""

if __name__ == '__main__':
	from Brain.planer.dialogs.MatchConfiguration import execute_gameconfiguration_dialog
	
	print 'Barabe Planer %s' % (VERSION, )
	
	## init PythonCard ..
	class TesT(model.Background):
		pass	
	app = model.Application(TesT, r'dialogs/minimal_app.rsrc.py')
	
	mach = None
	while 1:
		result = execute_gameconfiguration_dialog(mach)
		if result.accepted:
			mach = result.edited
			result = dialog.saveFileDialog(wildcard='*.match')
			if result.accepted:
				filepath = result.paths[0]
				pickle.dump(mach, open(filepath, 'wb'))
		else:
			break






